<!DOCTYPE html>
<html>
<head>
  <title>CQRS - Bookstore</title>
  <link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css"
        rel="stylesheet"/>
</head>
<body>

<div class="container" style="width:80%">
  <h1>Welcome to the CQRS bookstore</h1>

  <h2>Available books:</h2>

  <div class="well">
    <table class="table" id="book-list">
      <thead>
      <tr>
        <th></th>
        <th>Book Title</th>
        <th style="text-align: right">Price</th>
        <th>&nbsp;</th>
      </tr>
      </thead>

      <tbody></tbody>
    </table>
  </div>

  <hr/>

  <div>
    <h5>Shopping cart</h5>

    <div style="width:40%" class="well">
      <span id="empty-cart"><em>Cart is empty</em></span>
      <table class="table table-condensed" id="cart">
        <thead>
        <tr>
          <th>Item</th>
          <th style="text-align: right">Quantity</th>
          <th style="text-align: right">Price</th>
        </tr>
        </thead>
        <tbody></tbody>
      </table>
    </div>
    <div>
      <button id="btn-clear-cart" class="btn btn-info">Clear cart</button>
    </div>

  </div>

  <hr/>

  <div id="order-info">
    <form class="form-horizontal">
      <fieldset>

        <div id="order-result-message"></div>
        <!-- Address form -->
        <h2>Order information</h2>

        <!-- full-name input-->
        <div class="control-group">
          <label for="customerName" class="control-label">Full Name</label>

          <div class="controls">
            <input id="customerName" name="full-name" type="text" placeholder="John Doe"
                   class="input-xlarge"/>
          </div>
        </div>

        <!-- address-->
        <div class="control-group">
          <label for="customerAddress" class="control-label">Address</label>

          <div class="controls">
            <input id="customerAddress" name="address" type="text" placeholder="Highway street 1"
                   class="input-xlarge"/>
          </div>
        </div>

        <!-- email input-->
        <div class="control-group">
          <label for="customerEmail" class="control-label">Email</label>

          <div class="controls">
            <input id="customerEmail" name="email" type="email" placeholder="john.doe@acme.com"
                   class="input-xlarge"/>
          </div>
        </div>

        <!-- Submit -->
        <div class="control-group">
          <div class="controls">
            <button id="btn-place-order" class="btn btn-success">Place order</button>
          </div>
        </div>

      </fieldset>
    </form>
  </div>
</div>

<!-- Latest compiled and minified JavaScript -->

<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.0/jquery.cookie.min.js"></script>

<!-- Load all books -->
<script language="javascript">

var shoppingService = "/service/carts/";
var productCatalogService = "http://localhost:8090/products";
var orderService = "http://localhost:8070/service/order-requests";

$(document).ready(function () {
  loadAndRenderProducts();
  if (!hasCartIdCookie()) {
    initCart(loadCart);
  } else {
    loadCart();
  }
});

$(document).on("click", "#book-list button", function () {
  var buttonId = this.id;
  var productId = buttonId.replace("#add-item-", "");
  var url = shoppingService + getCartIdFromCookie() + "/items";
  var payload = JSON.stringify({"productId": productId });
  postJSON(url, payload)
      .error(function (data) {
        alert("Error: " + data);
      })
      .done(loadCart);
});

$('#btn-place-order').click(function () {
  placeOrder();
  return false;
});

$('#btn-clear-cart').click(function () {
  deleteCart(function (result) {
    initCart(loadCart);
  });
  return false;
});

function hasCartIdCookie() {
  return !(getCartIdFromCookie() === undefined);
}

function getCartIdFromCookie() {
  return $.cookie('cart');
}

function deleteCart(onSuccess) {
  var cartId = getCartIdFromCookie();
  console.log("Deleting session: " + cartId);
  $.ajax({
    url: shoppingService + cartId,
    type: 'DELETE',
    success: onSuccess
  });
}

function initCart(onDone) {
  $.removeCookie("cart");
  var newCartId = guid();
  postJSON(shoppingService, JSON.stringify({"cartId": newCartId }))
      .error(function (data) {
        alert("Error: " + data);
      })
      .done(function () {
        console.log("Successfully initialized new session: " + newCartId);
        $.cookie('cart', newCartId);
        onDone();
      });
}

function loadCart() {
  var sessionId = getCartIdFromCookie();
  $.ajax({
    'type': 'GET',
    'url': shoppingService + sessionId,
    'accept': 'application/json',
    'success': function (cart) {
      console.log("Loaded cart for session: " + sessionId);
      renderCart(cart);
    },
    'error': function (data) {
      if (data.status == 404) {
        console.log("Could not find cart for session [" + sessionId + "]");
        $.removeCookie("cart");
      }
    }
  });
}

function renderCart(cart) {
  var cartSelector = $('#cart');
  cartSelector.find("tbody tr").remove();

  if (cart.length === null) {
    cartSelector.hide();
    $('#empty-cart').show();
  } else {
    $('#empty-cart').hide();
    renderCartItems(cart);
  }
}

function renderCartItems(cart) {
  var cartSelector = $('#cart');
  $.each(cart.lineItems, function (index, lineItem) {
    var productId = lineItem.productId;
    var title = lineItem.title;
    var price = lineItem.price;
    var qty = lineItem.quantity;
    var totalPrice = lineItem.totalPrice;
    cartSelector.find("tbody")
        .append('<tr><td>' + title + '</td>' +
            '<td><p class="text-right">' + qty + '</p></td>' +
            '<td><p class="text-right">' + toDollarString(totalPrice) + '</p></td></tr>');
    cartSelector.show();
  });
  cartSelector.find("tbody tr:last").after(
      '<tr><td><b>Totals:</b></td>' +
          '<td><p class="text-right"><b>' + cart.totalQuantity + '</b></p></td>' +
          '<td><p class="text-right"><b>' + toDollarString(cart.totalPrice) + '</p></b></td></tr>');

}

function toDollarString(moneyInCents) {
  return "$ " + (moneyInCents / 100).toFixed(2);
}

function loadAndRenderProducts() {
  $.getJSON(productCatalogService, function (products) {
    renderProducts(products);
  });
}

function renderProducts(products) {
  var list = products == null ? [] : (products instanceof Array ? products : [products]);
  var bookListSelector = $('#book-list');
  bookListSelector.find('tbody').remove();
  $.each(list, function (index, product) {
    var book = product.book;
    var itemId = 'add-item-' + product.productId;
    bookListSelector.append(
        '<tr><td><img id=' + book.isbn + ' height="80px" width="65px"/></td>' +
            '<td>' + book.title + '</td>' +
            '<td><p class="text-right">' + toDollarString(product.price) + '</p></td>' +
            '<td><button class="btn-small btn-success" id="#' + itemId + '">Add</button></td></tr>');
  });
  $.each(list, function (index, product) {
    getCoverImageUrl(product.book.isbn, function (imageUrl) {
      $('#' + product.book.isbn).attr("src", imageUrl);
    });
  });
}

function getCoverImageUrl(isbn, callback) {
  $.ajax({
    url: 'https://www.googleapis.com/books/v1/volumes?q=isbn:' + isbn,
    dataType: 'json',
    success: function (data) {
      if (data.items != undefined) {
        callback(data.items[0].volumeInfo.imageLinks.smallThumbnail);
      }
    },
    error: function (data) {
      console.log('Got error: ' + data.error.message + ' when getting ' + isbn);
      callback("book.png");
    }
  });
}

function placeOrder() {
  console.log("Placing order...");
  var sessionId = getCartIdFromCookie();
  $.getJSON(shoppingService + sessionId, function (cart) {
    console.log("Reading contents in session: " + JSON.stringify(cart));
    postJSON(orderService, createOrderRequestJson(cart))
        .error(function (data) {
          var message = '<div class="alert alert-error">' +
              '<span>There was an error processing your order</span>' +
              '</div>';
          $("#order-result-message").html(message).show().delay(3000).fadeOut();
        })
        .done(function (data) {
          var message = '<div class="alert alert-success">' +
              '<span>Order was successfully placed!</span>' +
              '</div>';
          $("#order-result-message").html(message).show().delay(3000).fadeOut();
          deleteCart(function () {
            initCart(loadCart);
          });
          $("#order-info input").val("");
        });
  });
}

function createOrderRequestJson(cart) {
  console.log("Sending cart: " + JSON.stringify(cart));
  return JSON.stringify({
    "cart": cart,
    "orderId": guid(),
    "customerName": $('#customerName').val(),
    "customerEmail": $('#customerEmail').val(),
    "customerAddress": $('#customerAddress').val()
  });
}

function postJSON(url, data, callback) {
  return $.ajax({
    'type': 'POST',
    'url': url,
    'contentType': 'application/json',
    'data': data,
    'dataType': 'json',
    'success': callback
  });
}

/**
 * Generates a GUID string.
 * @returns {String} The generated GUID.
 * @example af8a8416-6e18-a307-bd9c-f2c947bbb3aa
 * @author Slavik Meltser (slavik@meltser.info).
 * @link http://slavik.meltser.info/?p=142
 */
function guid() {
  function _p8(s) {
    var p = (Math.random().toString(16) + "000000000").substr(2, 8);
    return s ? "-" + p.substr(0, 4) + "-" + p.substr(4, 4) : p;
  }

  return _p8() + _p8(true) + _p8(true) + _p8();
}

</script>

</body>
</html>